package com.java.day07jdbc;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * JDBC工具类
 */
public class JDBCUtils {

    public static final String URL = "jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT&characterEncoding=UTF-8&useUnicode=true&useSSL=false";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "123456";

    /**
     * 执行增删改
     * @param sql SQL语句
     * @param params 可变参数，SQL语句参数的值
     * @return 行数
     */
    public static int executeUpdate(String sql,Object... params){
        //创建连接，自动关闭
        try(Connection connection = DriverManager.getConnection(URL,USERNAME,PASSWORD)){
            //创建命令对象
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            //设置占位符参数
            for(int i = 0;i < params.length;i++){
                preparedStatement.setObject(i + 1,params[i]);
            }
            //执行命令
            int rows = preparedStatement.executeUpdate();
            return rows;
        }catch (SQLException ex){
            ex.printStackTrace();
            //向上抛出异常
            throw new RuntimeException(ex);
        }
    }

    /**
     * 执行查询操作
     * @param clazz 要查询的实体类类型 如： Student.class
     * @param sql SQL语句
     * @param params 占位符参数
     * @param <T> 泛型类型
     * @return 泛型集合
     */
    public static <T> List<T> executeQuery(Class clazz,String sql,Object... params){
        try(Connection connection = DriverManager.getConnection(URL,USERNAME,PASSWORD)){
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            for(int i = 0;i < params.length;i++){
                preparedStatement.setObject(i + 1,params[i]);
            }
            //执行查询获得ResultSet
            ResultSet rs = preparedStatement.executeQuery();
            //创建List集合
            List<T> list = new ArrayList<>();
            //遍历结果集
            while(rs.next()){
                //使用反射机制创建对象 new Student();
                Object object = clazz.newInstance();
                //给对象的所有属性赋值
                //使用反射获得类中所有属性 Student id name age gender address
                Field[] fields = clazz.getDeclaredFields();
                //遍历所有属性
                for(Field field : fields){
                    //通过属性名，将结果集中的列的值读出来
                    Object value = rs.getObject(field.getName());
                    //设置属性可以访问
                    field.setAccessible(true);
                    //给属性赋值 对象.属性 = 值
                    field.set(object,value);
                }
                //添加对象到List集合
                list.add((T)object);
            }
            return list;
        }catch (Exception ex){
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }
}
